package com.liusand.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.IdUtil;
import com.liusand.common.ThreadLocalUtils;
import com.liusand.dto.DishFlavorsDto;
import com.liusand.dto.FlavorsDto;
import com.liusand.exception.DishException;
import com.liusand.mapper.CategoryMapper;
import com.liusand.mapper.DishMapper;
import com.liusand.pojo.Category;
import com.liusand.pojo.Dish;
import com.liusand.pojo.Flavors;
import com.liusand.pojo.PageInfo;
import com.liusand.service.DishService;
import com.liusand.vo.ClientDishVo;
import com.liusand.vo.DishFlavorsVo;
import com.liusand.vo.DishVo;
import com.liusand.vo.FlavorsVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author :liusha
 * packageName :com.liusand.service.impl
 * fileName :DishServiceImpl
 * creationTime :2022/11/23 21:03
 */
@Service
public class DishServiceImpl implements DishService {
    @Autowired
    private DishMapper dishMapper;
    @Autowired
    private CategoryMapper categoryMapper;

    @Override
    public DishFlavorsVo findDishFlavorsVoById(String id) {
        Dish dish = dishMapper.findDishById(id);
        if(dish == null){
            return null;
        }
        List<Flavors> flavors = dishMapper.findFlavorsByDishId(id);
        if(flavors == null){
            return null;
        }
        DishFlavorsVo dishFlavorsVo = new DishFlavorsVo();
        BeanUtils.copyProperties(dish, dishFlavorsVo);
        dishFlavorsVo.setFlavors(flavors);
        Category category = categoryMapper.findCategoryById(dishFlavorsVo.getCategoryId());
        if(category == null){
            return null;
        }
        dishFlavorsVo.setCategoryName(category.getName());
        return dishFlavorsVo;
    }

    @Override
    public PageInfo<DishVo> page(String name, Integer page, Integer pageSize, String type) {
        Integer t;
        if(StringUtils.hasText(type)){
            t = Integer.parseInt(type);
        }else{
            t = null;
        }
        Integer start = (page - 1) * pageSize;
        List<DishVo> vos = dishMapper.page(name, start, pageSize, t);
        PageInfo<DishVo> pageInfo = new PageInfo<>();
        pageInfo.setRecords(vos);
        pageInfo.setSize(pageSize);
        pageInfo.setCurrent(page);
        pageInfo.setTotal(dishMapper.countPage(name, t));
        return pageInfo;
    }

    @Override
    public List<DishFlavorsVo> list(String id) {
        List<DishFlavorsVo> list = dishMapper.list(id);
        for(DishFlavorsVo vo : list){
            List<Flavors> flavors = dishMapper.findFlavorsByDishId(vo.getId());
            vo.setFlavors(flavors);
        }
        return list;
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public boolean saveDish(DishFlavorsDto dishFlavorsDto) {
        Dish dish = new Dish();
        BeanUtils.copyProperties(dishFlavorsDto, dish);
        String dishId = IdUtil.getSnowflakeNextIdStr();
        dish.setId(dishId);
        dish.setType(0);
        dish.setSort(0);
        String id = ThreadLocalUtils.getId();
        dish.setCreateUser(id);
        dish.setUpdateUser(id);
        Integer dishResult = dishMapper.saveDish(dish);


        List<FlavorsDto> flavorsDtoList = dishFlavorsDto.getFlavors();
        if(CollectionUtils.isEmpty(flavorsDtoList)){
            return true;
        }
        List<Flavors> flavors = new ArrayList<>();
        for(FlavorsDto flavorsDto : flavorsDtoList){
            if(flavorsDto == null){
                continue;
            }
            Flavors f = new Flavors();
            BeanUtils.copyProperties(flavorsDto, f);
            f.setId(IdUtil.getSnowflakeNextIdStr());
            f.setCreateUser(id);
            f.setUpdateUser(id);
            f.setDishId(dishId);
            f.setIsDeleted(0);
            flavors.add(f);
        }
        Integer flavorsResult = dishMapper.saveFlavors(flavors);

        if(dishResult == 0 || flavorsResult != flavors.size()){
            throw new DishException("新增菜品错误");
        }
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateDish(DishFlavorsDto dishFlavorsDto){
        Dish dish = new Dish();
        BeanUtils.copyProperties(dishFlavorsDto, dish);
        Integer dishResult = dishMapper.updateDish(dish);

        List<FlavorsDto> flavorsDtoList = dishFlavorsDto.getFlavors();
        if(CollectionUtils.isEmpty(flavorsDtoList)){
            return true;
        }
        List<String> ids = new ArrayList<>();
        ids.add(dish.getId());
        Integer re = dishMapper.deleteFlavorsByDishId(ids);

        String id = ThreadLocalUtils.getId();

        List<Flavors> flavors = new ArrayList<>();
        for(FlavorsDto flavorsDto : flavorsDtoList){
            if(flavorsDto == null){
                continue;
            }
            Flavors f = new Flavors();
            BeanUtils.copyProperties(flavorsDto, f);
            f.setId(IdUtil.getSnowflakeNextIdStr());
            f.setCreateUser(id);
            f.setUpdateUser(id);
            f.setDishId(dish.getId());
            f.setIsDeleted(0);
            flavors.add(f);
        }
        Integer flavorsResult = dishMapper.saveFlavors(flavors);

        if(dishResult == 0 && re == 0 && flavorsResult != flavors.size()){
            throw new DishException("菜品修改异常");
        }
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteDish(List<String> ids) {
        Integer flavorsResult = dishMapper.deleteFlavorsByDishId(ids);

        Integer dishResult = dishMapper.deleteDish(ids);

        if(flavorsResult == 0 || dishResult == 0){
            throw new DishException("添加失败");
        }
        return true;
    }

    @Override
    public boolean updateStatus(Integer status, List<String> ids) {
        Integer re = dishMapper.updateStatus(status, ids);
        if(re == 0){
            throw new DishException("修改失败");
        }
        return true;
    }

    @Override
    public List<ClientDishVo> clientList(String categoryId, Integer status) {
        List<Dish> dishes = dishMapper.findDishByCategoryIdAndStatus(categoryId, status);
        if(dishes == null){
            return null;
        }
        List<ClientDishVo> clientDishVoList = BeanUtil.copyToList(dishes, ClientDishVo.class);
        Set<String> dishIds = dishes.stream().map(Dish::getId).collect(Collectors.toSet());
        List<FlavorsVo> flavorsList = dishMapper.findFlavorsByDishIds(dishIds);
        if(flavorsList == null){
            return clientDishVoList;
        }
        Map<String, List<FlavorsVo>> flavorsByDishId = flavorsList.stream().collect(Collectors.groupingBy(FlavorsVo::getDishId));
        for(ClientDishVo vo : clientDishVoList){
            vo.setNumber(0);
            String id = vo.getId();
            List<FlavorsVo> flavorsVos = flavorsByDishId.get(id);
            vo.setFlavors(flavorsVos);
        }
        return clientDishVoList;
    }
}
